<!DOCTYPE html>
<html>

<head>
  <script src="./js/vue.js"></script>
  <link rel="stylesheet" href="./css/element.css">
  <script src="./js/element.js"></script>
  <title>CmdBox [ by QQ374974183 ]</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
      background-color: #f5f7fa;
    }

    h2 {
      color: #333;
    }

    label {
      display: block;
      margin-bottom: 10px;
      color: #555;
      font-weight: 500;
    }

    input {
      width: 150px;
      padding: 8px 12px;
      border-radius: 6px;
      border: 1px solid #dcdfe6;
      transition: all 0.3s;
    }

    input:focus {
      border-color: #409eff;
      outline: none;
      box-shadow: 0 0 0 2px rgba(64,158,255,.2);
    }

    button {
      padding: 8px 16px;
      background-color: #409eff;
      color: white;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      transition: all 0.3s;
    }

    button:hover {
      background-color: #66b1ff;
      transform: translateY(-1px);
    }

    html,
    body {
      overflow-x: hidden;
    }

    span {
      display: inline-block;
      width: 100px;
      font-weight: 500;
    }

    .line {
      margin: 24px 0;
      padding: 16px;
      background: white;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
      transition: all 0.3s;
    }

    .line:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 16px 0 rgba(0,0,0,.1);
    }

    ::-webkit-scrollbar {
      width: 4px;
    }

    ::-webkit-scrollbar-track {
      background-color: #f1f1f1;
      border-radius: 2px;
    }

    ::-webkit-scrollbar-thumb {
      background-color: #909399;
      border-radius: 2px;
    }

    ::-webkit-scrollbar-thumb:hover {
      background-color: #606266;
    }

    .el-dialog__header {
      padding: 0 !important;
    }

    .el-link {
      font-size: 20px !important;
      margin-right: 16px;
      transition: all 0.3s;
    }

    .el-link:hover {
      transform: scale(1.1);
    }

    input {
      margin-right: 16px;
    }

    .accredit-info {
      width: 100%;
      margin: auto;
      text-align: center;
      color: #67c23a;
      font-size: 28px;
      padding: 40px 0;
    }

    .el-dialog {
      border-radius: 8px;
    }

    .el-dialog__body {
      padding: 24px;
    }

    .el-input {
      margin-bottom: 16px;
    }

    .dialog-footer {
      padding: 16px 0 0;
    }

    .website-info {
      text-align: center;
      padding: 20px 0;
      color: #606266;
      font-size: 14px;
    }

    .website-info a {
      color: #409eff;
      text-decoration: none;
    }

    .website-info a:hover {
      color: #66b1ff;
    }
  </style>
</head>

<body>
<div id="app" v-loading="loading">


  <div class="line" style="max-width: 500px; margin: 0 auto;" v-if="accreditInfo.success">
    <span for="port">关闭端口:</span>
    <input type="number" id="port" min="1" max="65535" v-model="port">

    <el-tooltip content="关闭" placement="top">
      <el-link icon="el-icon-circle-close" :underline="false" @click="closePort"></el-link>
    </el-tooltip>

    <el-tooltip content="设置命令" placement="top">
      <el-link icon="el-icon-circle-plus-outline" :underline="false" @click="addCmd"></el-link>
    </el-tooltip>
  </div>

  <div class="line" style="max-width: 500px; margin: 12px auto;" v-if="accreditInfo.success">
    <span for="port">关闭进程:</span>
    <input type="text" id="process" v-model="process" disabled>

    <el-tooltip content="关闭" placement="top">
      <el-link icon="el-icon-circle-close" :underline="false" @click="closeProcess"></el-link>
    </el-tooltip>

    <el-tooltip content="选择" placement="top" v-if="!selected">
      <el-link icon="el-icon-rank" :underline="false" @click="getProcessName"></el-link>
    </el-tooltip>

    <el-tooltip v-if="selected" content="取消" placement="top" v-if="!selected">
      <el-link icon="el-icon-circle-check" :underline="false" @click="cancelGetProcessName"></el-link>
    </el-tooltip>
  </div>

  <div class="line" style="max-width: 500px; margin: 12px auto;" v-for="(item, index) in commands" :key="index"
       v-if="accreditInfo.success">
    <span for="port">{{item.desc}}:</span>
    <input type="text" v-model="item.cmd" disabled />

    <el-tooltip content="执行" placement="top">
      <el-link icon="el-icon-s-promotion" :underline="false" @click="execCmd(item)"></el-link>
    </el-tooltip>

    <el-tooltip content="编辑" placement="top">
      <el-link icon="el-icon-edit" :underline="false" @click="editCmd(item, index)"></el-link>
    </el-tooltip>

    <el-tooltip content="删除" placement="top">
      <el-link icon="el-icon-remove-outline" :underline="false" @click="delCmd(index)"></el-link>
    </el-tooltip>

    <el-tooltip content="关闭" placement="top">
      <el-link icon="el-icon-circle-close" :underline="false" @click="closePort1(item.port)"></el-link>
    </el-tooltip>

    <el-tooltip content="查看" placement="top">
      <el-link icon="el-icon-view" :underline="false" @click="findPort(item.port)"></el-link>
    </el-tooltip>
  </div>
  <div v-if="accreditInfo.expireTs" style="font-size: 14px; margin-bottom: 12px; text-align: center; color: #606266;">过期时间：{{accreditInfo.expireTs}}</div>
  <el-dialog :visible.sync="dialogVisible" width="60%" v-if="accreditInfo.success">
    <div>
      <label>命令:</label>
      <el-input v-model="command.cmd" @input="handleCmdInput"></el-input>
    </div>
    <div>
      <label>描述:</label>
      <el-input v-model="command.desc"></el-input>
    </div>
    <div>
      <label>执行次数:</label>
      <el-input v-model="command.count"></el-input>
    </div>
    <div>
      <label>端口:</label>
      <el-input type="number" min="1" max="65535" v-model="command.port"></el-input>
    </div>
    <div>
      <div v-for="(arg, index) in command.args" :key="index">
        <span>参数{{index}}:</span>
        <el-input v-model="arg.name" placeholder="名称"></el-input>
        <el-input v-model="arg.value" placeholder="默认值"></el-input>
      </div>
    </div>
    <div slot="footer" class="dialog-footer" style="display: flex; justify-content: center;">
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="saveCommand">保存</el-button>
    </div>
  </el-dialog>

  <div class="accredit-info" v-if="!accreditInfo.success">
    <div>{{accreditInfo.msg}}</div>
    <div v-if="accreditInfo.expireTs">过期时间：{{accreditInfo.expireTs}}</div>
  </div>

  <div class="website-info">
    <a href="https://www.poying.space" target="_blank">&copy; 秋风要萧瑟了 [www.poying.space]</a>
  </div>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      port: '',
      commands: [],
      dialogVisible: false,
      command: {
        cmd: '',
        desc: '',
        args: []
      },
      index: -1,
      process: "",
      selected: false,
      accreditInfo: {
        success: true,
        msg: null,
        expireTs: null
      },
      loading: false,
    },
    created() {
      coustom.receiveFromMain("read-command", (err, data) => {
        this.commands = JSON.parse(data);
        console.log(123123, this.commands);
      })

      coustom.receiveFromMain("error", (err, data) => {
        this.$message({ type: "error", message: data, duration: 1000 });
      })

      coustom.receiveFromMain("info", (err, data) => {
        this.$message({ type: "success", message: data, duration: 1000 });
      }),

              coustom.receiveFromMain("processName", (err, data) => {
                this.process = data;
                this.selected = false;
                this.$message({ type: "success", message: data, duration: 1000 });
              }),

              coustom.receiveFromMain("port-pids", (err, data) => {
                let { port, pids } = data;
                let msg = `【${port}】 端口未开启`;
                if (pids.length < 2) {
                  this.$message({ type: 'error', message: msg, duration: 1000 });
                } else {
                  pids = pids.filter((item) => {
                    return item != ""
                  })
                  msg = `【${port}】 端口开启成功 => pids: ` + pids.join(",");
                  this.$message({ type: "success", message: msg, duration: 1000 });
                }

              })

      coustom.receiveFromMain("accredit-info", (err, data) => {
        this.loading = false;
        this.accreditInfo = {
          ...data
        };
      })
    },
    mounted() {
    },
    methods: {
      cancelGetProcessName() {
        this.selected = false;
        coustom.sendToMain("cancelGetProcessName");
      },
      getProcessName() {
        this.selected = true;
        coustom.sendToMain("getProcessName");
      },
      closeProcess() {
        coustom.sendToMain("close-process", this.process);
      },
      handleCmdInput(val) {
        this.command.args = [];
        for (let i = 0; i < val.replaceAll(/[^?]/g, "").length; i++) {
          this.command.args.push({
            value: null,
            name: null,
          });
        }
      },
      addCmd(item) {
        this.index = -1;
        this.command = {
          args: []
        };
        this.dialogVisible = true;
      },
      updateCmd() {
        coustom.sendToMain("update-cmd", JSON.stringify(this.commands));
      },
      editCmd(item, index) {
        this.index = index;
        this.command = { ...item };
        this.dialogVisible = true;
      },
      delCmd(index) {
        this.commands.splice(index, 1);
        this.updateCmd();
      },

      saveCommand() {
        if (this.index == -1) {
          if (this.command.desc && this.command.cmd) {
            this.commands.unshift({
              ...this.command
            });
            this.updateCmd();
            this.dialogVisible = false;
          }
        } else {
          if (this.command.desc && this.command.cmd) {
            this.commands.splice(this.index, 1, { ...this.command });
            this.updateCmd();
            this.dialogVisible = false;
          }
        }

      },
      execCmd(item) {
        let argsLen = item.cmd.replaceAll(/[^?]/g, "").length;
        for (let i = 0; i < argsLen; i++) {
          if (!item.args[i].value) {
            this.$message({ type: 'info', message: "参数命令,请设置默认参数后执行", duration: 1000 });
            this.editCmd(item);
            return;
          }
        }
        coustom.sendToMain("exec-cmd", JSON.stringify(item));
      },
      closePort() {
        if (!this.port) {
          return;
        }
        const port = this.port;
        coustom.sendToMain("kill-port", port);
        console.log('关闭端口:', port);
        this.port = '';
      },
      closePort1(port) {
        coustom.sendToMain("kill-port", port);
      },
      findPort(port) {
        coustom.sendToMain("find-port", port);
      }
    }
  });
</script>
</body>

</html>
